#!/usr/bin/php
<?php

require_once __DIR__.DIRECTORY_SEPARATOR."input.php";
require_once __DIR__.DIRECTORY_SEPARATOR."vt.php";

class shell
{
    private $input;
    static private $path = null;
    private $history = array();

    public function __construct()
    {
        $this->input = new input();
        self::$path = explode(":", getenv("PATH"));
    }

    public function keyhandle($key, & $obj)
    {
        switch ($key)
        {
            case input::UP:
                break;
            case input::DOWN:
                break;
            case input::LEFT:
                if ($obj->pos < 0)
                    break;
                vt::move(1, vt::DIR_LEFT);
                $obj->pos--;
                break;
            case input::RIGHT:
                vt::move(1, vt::DIR_RIGHT);
                $obj->pos++;
                break;
            case input::ENTER:
                break;
            default:
                $obj->s .= chr($key);
                $obj->len++;
                $obj->pos++;
                break;
        }
    }

    public function getInput()
    {
        $s = "";
        $pos = 0;
        vt::cursor(vt::CUR_SAVE);
        while (1)
        {
            $key = $this->input->get();
            if ($key == input::ENTER) {
                break;
            } else if ($key == input::BS) {
                if ($pos < 1)
                    continue;
                vt::bs();
                $s = substr($s, 0, --$pos);
            } else if ($key == input::UP) {
                $s = end($this->histroy);
                vt::cursor(vt::CUR_LOAD);
                vt::clean(vt::CLEAN_LINE);
                $pos = strlen($s);
                echo $s;
            } else {
                $ch = chr($key);
                $s .= $ch;
                $pos++;
                vt::cursor(vt::CUR_LOAD);
                vt::clean(vt::CLEAN_LINE);
                echo $s;
            }
        }

        // echo gettype($s), PHP_EOL;

        return $s;
    }

    static public function getpath($command)
    {
        $pos = strpos($command, " ");
        if ($pos === FALSE)
            $execfile = $command;
        else
            $execfile = substr($command, 0, $pos);

        if (file_exists($execfile))
            return $execfile;

        // echo $execfile, PHP_EOL;

        foreach (self::$path as $val) {
            $path = $val.DIRECTORY_SEPARATOR.$execfile;
            if (file_exists($path))
                return $path;
        }

        return null;
    }

    static public function getarg($command)
    {
        if (strpos($command, " ") === FALSE)
            return null;
        $arg = explode(" ", $command);
        array_shift($arg);
        return $arg;
    }

    public function exec($command)
    {
        echo PHP_EOL;

        if ($command == "" || $command == null)
            return;

        $execfile = self::getpath($command);
        if ($execfile == NULL) {
            printf("$command 命令不存在!\n");
            return;
        }
        $arg = self::getarg($command);
        if ($arg == NULL) {
            $arg = array();
        }
        // echo $execfile, PHP_EOL;
        $this->histroy[] = $command;

        if (pcntl_fork() == 0) {
            pcntl_exec($execfile, $arg);
            exit(0);
        }
        pcntl_wait($status);
    }


    public function run()
    {
        while (1)
        {
            printf("[kyo]# ");
            $s = $this->getInput();
            // echo $s, PHP_EOL;
            if (trim($s) == "exit")
                break;
            $this->exec($s);
        }
        echo PHP_EOL;
    }
}

function main($argc, & $argv)
{
    $shell = new shell();
    $shell->run();

    return 0;
}

exit(main($argc, $argv));


